package pl.polsl.mmm.projectcomm.objects;

import pl.polsl.mmm.projectcomm.data.VertexArray;
import pl.polsl.mmm.projectcomm.programs.TextureShaderProgram;

import static android.opengl.GLES20.GL_TRIANGLES;
import static android.opengl.GLES20.glDrawArrays;
import static pl.polsl.mmm.projectcomm.Constants.BYTES_PER_FLOAT;

/**
 * Created by Maciek on 2014-10-15.
 */
public class OBJ {
    private static final int POSITION_COMPONENT_COUNT = 3;
    private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
    private static final int POSITION_TEXTURE_SUM_COUNT = POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT;
    private static final int STRIDE = (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;


    private int texels, vertices, faces, normals;
    private float[][] positionData; //tablica wierzchołków
    private float[][] texelData; // tablica wsp. texeli
    private float[][] normalsData; // tablica normalnych dla ścian
    private int[][] facesData; // tablica trójkątów
    private float[] vertexData;
    private VertexArray vertexArray;


    public OBJ(int texels, int vertices, int faces, int normals) {
        this.faces = faces;
        this.texels = texels;
        this.vertices = vertices;
        this.normals = normals;

        positionData = new float[vertices][3]; //[nrWierzch][XYZ]
        texelData = new float[texels][2]; // [nrCoord][UV]
        normalsData = new float[normals][3]; // [nrWekt][XYZ]
        facesData = new int[faces][9]; // [nrTrójk][P/T/N P/T/N P/T/N] position/texel/normal
        // ile wierzchołków = faces * 3
        // ile danych = wierzchołki * 5 zmiennych ( x,y,z,u,v )
        vertexData = new float[faces * 3 * POSITION_TEXTURE_SUM_COUNT ];
    }

    public void putVertexData(int idx, float x, float y, float z) {
        positionData[idx][0] = x;
        positionData[idx][1] = y;
        positionData[idx][2] = z;
    }

    public void putTexelData(int idx, float u, float v) {
        texelData[idx][0] = u;
        texelData[idx][1] = v;
    }

    public void putNormalData(int idx, float x, float y, float z) {
        normalsData[idx][0] = x;
        normalsData[idx][1] = y;
        normalsData[idx][2] = z;
    }

    public void putFacesData(int idx, int[] data) {
        for(int i=0;i<9;i++)
            facesData[idx][i] = data[i];
    }

    public void fillVertexData(){
        int vertexIndx = 0;
        for(int i=0;i<faces;i++) {
            // 0/3/6 - indeksy vertexów w tablicy facesData
            int vA = facesData[i][0] - 1;
            int vB = facesData[i][3] - 1;
            int vC = facesData[i][6] - 1;
            // 1/4/7 indexy texeli w tablicy facesData
            int tA = facesData[i][1] - 1;
            int tB = facesData[i][4] - 1;
            int tC = facesData[i][7] - 1;
            vertexData[vertexIndx++] = positionData [vA][0]; //xA
            vertexData[vertexIndx++] = positionData [vA][1]; //yA
            vertexData[vertexIndx++] = positionData [vA][2]; //zA
            vertexData[vertexIndx++] = texelData    [tA][0]; //uA
            vertexData[vertexIndx++] = texelData    [tA][1]; //vA

            vertexData[vertexIndx++] = positionData [vB][0]; //xB
            vertexData[vertexIndx++] = positionData [vB][1]; //yB
            vertexData[vertexIndx++] = positionData [vB][2]; //zB
            vertexData[vertexIndx++] = texelData    [tB][0]; //uB
            vertexData[vertexIndx++] = texelData    [tB][1]; //vB

            vertexData[vertexIndx++] = positionData [vC][0]; //xC
            vertexData[vertexIndx++] = positionData [vC][1]; //yC
            vertexData[vertexIndx++] = positionData [vC][2]; //zC
            vertexData[vertexIndx++] = texelData    [tC][0]; //uC
            vertexData[vertexIndx++] = texelData    [tC][1]; //vC

        }
        vertexArray = new VertexArray(vertexData);
    }
    public void bindData(TextureShaderProgram textureProgram) {
        vertexArray.setVertexAttribPointer(
                0,
                textureProgram.getPositionAttributeLocation(),
                POSITION_COMPONENT_COUNT,
                STRIDE);
/*
        vertexArray.setVertexAttribPointer(
                POSITION_COMPONENT_COUNT,
                textureProgram.getTextureCoordinatesAttributeLocation(),
                TEXTURE_COORDINATES_COMPONENT_COUNT,
                STRIDE);*/
    }

    public void draw() {
        glDrawArrays(GL_TRIANGLES, 0, faces * 3);
    }
}